package es.amh.gui;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.ByteArrayOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import net.miginfocom.swing.MigLayout;
import es.amh.data.BirthdayEntry;
import es.amh.management.BirthdayManagement;
import es.amh.management.CalendarManagement;
import es.amh.management.ICalendarManagement;
import javax.swing.JScrollBar;
import java.awt.Component;
import javax.swing.Box;
import java.awt.Dimension;
import javax.swing.JScrollPane;

@SuppressWarnings("serial")
public class BRQuickGUI extends JFrame {

	private JPanel contentPane;
	private JPasswordField txt_password;
	private JButton btnNewButton;
	private JTextField txt_email;
	private JProgressBar progressBar;
	private JLabel lblProgreso;
	private JTextArea textPane;

	PrintStream aPrintStream = new PrintStream(new FilteredStream(
			new ByteArrayOutputStream()));
	private Component horizontalStrut;
	private JScrollPane scrollPane;

	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					BRQuickGUI frame = new BRQuickGUI();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public BRQuickGUI() {
		 System.setOut(aPrintStream);
		 System.setErr(aPrintStream);
		
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new TitledBorder(null, "Birthday's Reminder", TitledBorder.LEADING, TitledBorder.TOP, null, Color.BLUE));
		setContentPane(contentPane);
		contentPane.setLayout(new MigLayout("", "[][grow][]", "[][][][][][grow][]"));
		
		JLabel lblEmail = new JLabel("Email:");
		lblEmail.setFont(new Font("Tahoma", Font.BOLD, 11));
		contentPane.add(lblEmail, "cell 0 0,alignx trailing");
		
		txt_email = new JTextField();
		contentPane.add(txt_email, "cell 1 0,growx");
		txt_email.setColumns(10);
		
		JLabel lblPassword = new JLabel("Password:");
		lblPassword.setFont(new Font("Tahoma", Font.BOLD, 11));
		lblPassword.setToolTipText("The password  is never stored");
		contentPane.add(lblPassword, "cell 0 1,alignx trailing");
		
		txt_password = new JPasswordField();
		contentPane.add(txt_password, "cell 1 1,growx");
		
		horizontalStrut = Box.createHorizontalStrut(20);
		contentPane.add(horizontalStrut, "cell 2 1");
		
		JSeparator separator = new JSeparator();
		contentPane.add(separator, "cell 0 2 2 1,alignx center,growy");
		
		btnNewButton = new JButton("Don't forget more Birthdays!");
		btnNewButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				String[] credentials = getCredentials();
				if (validateCredentials(credentials)) {
					startProcess(credentials);
				} else {
					appendResult("Please, check your email");
				}
			}
		});
		contentPane.add(btnNewButton, "cell 0 3 2 1,alignx center");
		
		lblProgreso = new JLabel("Progress:");
		lblProgreso.setFont(new Font("Tahoma", Font.BOLD, 11));
		contentPane.add(lblProgreso, "cell 0 4");
		
		progressBar = new JProgressBar();
		progressBar.setStringPainted(true);
		contentPane.add(progressBar, "cell 1 4,grow");
		
		scrollPane = new JScrollPane();
		contentPane.add(scrollPane, "cell 0 5 2 2,grow");
		
		textPane = new JTextArea();
		scrollPane.setViewportView(textPane);
		textPane.setAutoscrolls(true);
		textPane.setEditable(false);
		textPane.setBorder(new TitledBorder("Log:"));
	}

	protected boolean validateCredentials(String[] credentials) {
		return true;
	}

	protected void appendResult(String text) {
		this.textPane.append("\n"+ text);
	}

	protected String[] getCredentials() {
		
		
		String[] credentials = new String[2];
		credentials[0] = txt_email.getText();
		credentials[1] = new String(txt_password.getPassword());
		return credentials;
	}

	protected void startProcess(String[] credentials) {
		MainProcess process = new MainProcess(credentials, progressBar);
		process.start();
		
	}

	private class MainProcess extends Thread {

		private JProgressBar progressBar;
		private String user;
		private String password;

		public MainProcess(String[] credentials, JProgressBar progressBar) {
			this.progressBar = progressBar;
			this.user = credentials[0];
			this.password = credentials[1];
		}

		public void run() {
			// Create the contact management
			BirthdayManagement bm = BirthdayManagement.getInstance();
			bm.connectService(user, password);

			// Create the birthday management
			ICalendarManagement cm = CalendarManagement.getInstance();
			cm.connectService(user, password);

			// Retrieve the contacts
			appendResult("Retrieving the birthdays");
			try {
				List<BirthdayEntry> birthdays = bm.getListOfContact();
				// Commit the birthdays
				cm.createBirthdayCalendar();
				new UpdateProgressBar(cm, progressBar).start();
				cm.commitBirthdays(birthdays);
				
			} catch (Exception e) {
				appendResult("Fail");

			}
		}
	}
	
	private class UpdateProgressBar extends Thread {
		private JProgressBar progressBar;
		private ICalendarManagement cm;
		
		public UpdateProgressBar(ICalendarManagement _cm, JProgressBar _progressBar) {
			progressBar = _progressBar;
			cm = _cm;
		}
		
		public void run() {
			int progress = 0;
			while ((progress=cm.getProgress())!=100) {
				System.out.println("contando");
				progressBar.setValue(progress);
				progressBar.repaint();
				try {
					Thread.sleep(750);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			progressBar.setValue(100);
			progressBar.repaint();
		}
	}
	
	
	// **********************************************
	// ** REDIRECT STANDARD OUT / ERR TO TEXT AREA **
	// **********************************************
	class FilteredStream extends FilterOutputStream {
		public FilteredStream(OutputStream aStream) {
			super(aStream);
		}

		@Override
		public void write(byte b[]) throws IOException {
			String aString = new String(b);
			if (textPane != null) {
				appendResult(aString);
			}
		}

		@Override
		public void write(byte b[], int off, int len) throws IOException {
			String aString = new String(b, off, len);
			if (textPane != null) {
				appendResult(aString);
			}
		}
	}
	
}
